/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package facade;

import entity.Groups;
import entity.Role;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Resource;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.sql.DataSource;
import oracle.jdbc.OracleTypes;

/**
 *
 * @author Svetlana Shikhutskaya
 */
@Stateless
public class GroupsFacade extends AbstractFacade<Groups> implements GroupsFacadeLocal {

    @EJB
    private RoleFacadeLocal roleFacade;
    @PersistenceContext(unitName = "Delta-ejbPU")
    private EntityManager em;
    @Resource(mappedName = "jdbc/delta")
    private DataSource ds;

    @Override
    protected EntityManager getEntityManager() {
        return em;
    }

    public GroupsFacade() {
        super(Groups.class);
    }

    public Groups findByName(String groupName) {
        Query query = em.createNamedQuery("Groups.findByGroupName");
        query.setParameter("groupName", groupName);
        Groups group = null;
        try {
            group = (Groups) query.getSingleResult();
        } catch (NoResultException e) {
            Logger.getLogger(GroupsFacade.class.getName()).log(Level.SEVERE, null, e);
        }
        return group;
    }

    @Override
    public void createGroup(Groups group, String[] roles) {
        Groups gr = findByName(group.getGroupName());
        if (gr == null) {
            ArrayList<Role> listRole = new ArrayList<Role>();
            try {
                for (int i = 0; i < roles.length; i++) {
                    Role role = roleFacade.readByName(roles[i]);
                    listRole.add(role);
                }
                group.setRoleCollection(listRole);
                em.persist(group);
                for (int i = 0; i < roles.length; i++) {
                    listRole.get(i).getGroupsCollection().add(group);
                    em.merge(listRole.get(i));
                }
            } catch (NoResultException e) {
            }
        }
    }

    @Override
    public List<Groups> loadRangeOfGroups(int pageNumber, int pageCount) {
        List<Integer> ids=new ArrayList<Integer>();
        List<String> names = new ArrayList<String>();
        List<Groups> groups = new Vector<Groups>();
        HashMap<String, List<Role>> groupMap = new HashMap<String, List<Role>>();
        Connection conn = null;
        ResultSet rs = null;
        CallableStatement cstmt = null;
        try {
            conn = ds.getConnection();
            cstmt = conn.prepareCall("{call getGroups(?,?,?)}");
            cstmt.setInt("page_num", pageNumber);
            cstmt.setInt("page_count", pageCount);
            cstmt.registerOutParameter("p_refcur", OracleTypes.CURSOR);
            cstmt.executeUpdate();
            rs = (ResultSet) cstmt.getObject("p_refcur");
            while (rs.next()) {
                Integer id=rs.getInt("idGroup");
                String groupName = rs.getString("groupName");
                String roleName = rs.getString("roleName");
                Role role = roleFacade.readByName(roleName);
                if (groupMap.containsKey(groupName)) {
                    groupMap.get(groupName).add(role);
                } else {
                    names.add(groupName);
                    ids.add(id);
                    List<Role> temp = new ArrayList<Role>();
                    temp.add(role);
                    groupMap.put(groupName, temp);
                }
            }
            for (int i = 0; i < groupMap.size(); i++) {
                Groups group = new Groups(ids.get(i), names.get(i));
                group.setRoleCollection(groupMap.get(names.get(i)));
                groups.add(group);
            }
        } catch (SQLException ex) {
            Logger.getLogger(GroupsFacade.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            try {
                if (rs != null) {
                    rs.close();
                }
                if (cstmt != null) {
                    cstmt.close();
                }
                if (conn != null) {
                    conn.close();
                }
            } catch (SQLException ex) {
                Logger.getLogger(GroupsFacade.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        return groups;
    }
    
    @Override
    public long countGroups() {
        long count = (Long) em.createNamedQuery("Groups.count").getSingleResult();
        return count;
    }
}
